package com.yunhe.task.task;

import com.yunhe.common.model.data.PointNumberDTO;
import com.yunhe.task.client.AuthorityClient;
import com.yunhe.task.client.DeviceClient;
import com.yunhe.task.client.EnergyClient;
import com.yunhe.task.client.MeasHistoryClient;
import com.yunhe.common.constant.DeviceConsts;
import com.yunhe.common.model.DomainList;
import com.yunhe.common.model.authority.Firm;
import com.yunhe.common.model.authority.Station;
import com.yunhe.common.model.company.Company;
import com.yunhe.common.model.data.ElectricityDay;
import com.yunhe.common.model.data.ElectricityMonth;
import com.yunhe.common.model.data.Measurement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yunhe.common.util.CollectionUtil;

import java.util.*;

@Service
public class ElectricityTask {

    @Autowired
    private MeasHistoryClient measHistoryClient;
    @Autowired
    private DeviceClient deviceClient;
    @Autowired
    private AuthorityClient authorityClient;
    @Autowired
    private EnergyClient energyClient;

    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        System.out.println(Collections.singletonList(calendar.getTime()));
    }

    public void calculateDay(Long firmCode) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        List<Date> date = new ArrayList<>();
        date.addAll(Collections.singletonList(calendar.getTime()));
        date.addAll(Collections.singletonList(calendar.getTime()));
//        Calendar calendar1 = Calendar.getInstance();
//        calendar1.setTime(new Date());
//        calendar1.set(Calendar.HOUR_OF_DAY, 23);
//        calendar1.set(Calendar.MINUTE, 59);
//        calendar1.set(Calendar.SECOND, 59);
//        calendar1.set(Calendar.MILLISECOND, 59);
        List<Date> yesterday = new ArrayList<>();
//        date.addAll(Collections.singletonList(calendar1.getTime()));
        yesterday.addAll(Collections.singletonList(new Date(calendar.getTimeInMillis() - 1000 * 60 * 60 * 24)));
        yesterday.addAll(Collections.singletonList(new Date(calendar.getTimeInMillis() - 1000 * 60 * 60 * 24)));

        Firm firm = authorityClient.getFirmByCode(firmCode).getBody().getResults();
        List<Station> stations = authorityClient.getStationByFirmId(firm.getId()).getBody().getResults();
        if (stations != null) {
            List<ElectricityDay> electricityDayList = new ArrayList<>();
            double fPowerAll = 0L;
            double fPowerSharp = 0L;
            double fPowerPeak = 0L;
            double fPowerFlat = 0L;
            double fPowerValley = 0L;
            for (Station station : stations) {
                //获得电站点号对应
                Map<Long, List<Long>> powerAllPointMap = deviceClient.findStationPointNumber(
                        station.getId(), DeviceConsts.POINT_DATA_TYPE.PowerAll.value()).getBody().getResults();
                Map<Long, List<Long>> powerSharpPointMap = deviceClient.findStationPointNumber(
                        station.getId(), DeviceConsts.POINT_DATA_TYPE.PowerSharp.value()).getBody().getResults();
                Map<Long, List<Long>> powerPeakPointMap = deviceClient.findStationPointNumber(
                        station.getId(), DeviceConsts.POINT_DATA_TYPE.PowerPeak.value()).getBody().getResults();
                Map<Long, List<Long>> powerFlatPointMap = deviceClient.findStationPointNumber(
                        station.getId(), DeviceConsts.POINT_DATA_TYPE.PowerFlat.value()).getBody().getResults();
                Map<Long, List<Long>> powerValleyPointMap = deviceClient.findStationPointNumber(
                        station.getId(), DeviceConsts.POINT_DATA_TYPE.PowerValley.value()).getBody().getResults();

                //获得企业点号对应
                Map<Long, List<Long>> cPowerAllPointMap = deviceClient.findCompanyPointNumber(
                        station.getId(), DeviceConsts.POINT_DATA_TYPE.PowerAll.value()).getBody().getResults();
                Map<Long, List<Long>> cPowerSharpPointMap = deviceClient.findCompanyPointNumber(
                        station.getId(), DeviceConsts.POINT_DATA_TYPE.PowerSharp.value()).getBody().getResults();
                Map<Long, List<Long>> cPowerPeakPointMap = deviceClient.findCompanyPointNumber(
                        station.getId(), DeviceConsts.POINT_DATA_TYPE.PowerPeak.value()).getBody().getResults();
                Map<Long, List<Long>> cPowerFlatPointMap = deviceClient.findCompanyPointNumber(
                        station.getId(), DeviceConsts.POINT_DATA_TYPE.PowerFlat.value()).getBody().getResults();
                Map<Long, List<Long>> cPowerValleyPointMap = deviceClient.findCompanyPointNumber(
                        station.getId(), DeviceConsts.POINT_DATA_TYPE.PowerValley.value()).getBody().getResults();

                //组建所有点号列表
                List<Long> pointNumbers = new ArrayList<>();
                joinPointNumber(pointNumbers, powerAllPointMap);
                joinPointNumber(pointNumbers, powerSharpPointMap);
                joinPointNumber(pointNumbers, powerPeakPointMap);
                joinPointNumber(pointNumbers, powerFlatPointMap);
                joinPointNumber(pointNumbers, powerValleyPointMap);
                joinPointNumber(pointNumbers, cPowerAllPointMap);
                joinPointNumber(pointNumbers, cPowerSharpPointMap);
                joinPointNumber(pointNumbers, cPowerPeakPointMap);
                joinPointNumber(pointNumbers, cPowerFlatPointMap);
                joinPointNumber(pointNumbers, cPowerValleyPointMap);

                //获得今日点号值
                //DomainList<Long> pointNumbersDomain = new DomainList<>(pointNumbers);
                PointNumberDTO pointNumberDTO = new PointNumberDTO();
                pointNumberDTO.setPointNumbers(pointNumbers);
                List<List<Measurement>> dateMeasList = measHistoryClient.searchByPost(date , pointNumberDTO).getBody().getResults();
                Map<Long, Double> datePointValueMap = new HashMap<>();
                if(!CollectionUtil.isEmpty(dateMeasList)){
                    for (List<Measurement> dateMeas : dateMeasList) {
                        for (Measurement measurement : dateMeas) {
                            datePointValueMap.put(measurement.getPointNumber(), measurement.getVal());
                        }
                    }
                }
                //获得昨日点号值
                List<List<Measurement>> yesterdayMeasList = measHistoryClient.searchByPost(yesterday, pointNumberDTO).getBody().getResults();
                Map<Long, Double> yesterdayPointValueMap = new HashMap<>();
                if(!CollectionUtil.isEmpty(yesterdayMeasList)){
                    for (List<Measurement> yesterdayMeas : yesterdayMeasList) {
                        for (Measurement measurement : yesterdayMeas) {
                            yesterdayPointValueMap.put(measurement.getPointNumber(), measurement.getVal());
                        }
                    }
                }

                //添加电站电量
                ElectricityDay sElectricityDay = new ElectricityDay();
                sElectricityDay.setDtime(yesterday.get(0));
                sElectricityDay.setDeviceId(station.getId());
                double sPowerAll = getPointValue(station.getId(), powerAllPointMap, datePointValueMap, yesterdayPointValueMap);
                sElectricityDay.setVal(sPowerAll);
                double sPowerSharp = getPointValue(station.getId(), powerSharpPointMap, datePointValueMap, yesterdayPointValueMap);
                sElectricityDay.setSharp(sPowerSharp);
                double sPowerPeak = getPointValue(station.getId(), powerPeakPointMap, datePointValueMap, yesterdayPointValueMap);
                sElectricityDay.setPeak(sPowerPeak);
                double sPowerFlat = getPointValue(station.getId(), powerFlatPointMap, datePointValueMap, yesterdayPointValueMap);
                sElectricityDay.setFlat(sPowerFlat);
                double sPowerValley = getPointValue(station.getId(), powerValleyPointMap, datePointValueMap, yesterdayPointValueMap);
                sElectricityDay.setValley(sPowerValley);
                electricityDayList.add(sElectricityDay);

                //添加单位电量
                fPowerAll += sPowerAll;
                fPowerSharp += sPowerSharp;
                fPowerPeak += sPowerPeak;
                fPowerFlat += sPowerFlat;
                fPowerValley += sPowerValley;

                //添加企业电量
                List<Company> companys = authorityClient.getCompanys(station.getId()).getBody().getResults();
                if (companys != null) {
                    for (Company company : companys) {
                        ElectricityDay electricityDay = new ElectricityDay();
                        electricityDay.setDtime(yesterday.get(0));
                        electricityDay.setDeviceId(company.getId());
                        double powerAll = getPointValue(company.getId(), cPowerAllPointMap, datePointValueMap, yesterdayPointValueMap);
                        electricityDay.setVal(powerAll);
                        double powerSharp = getPointValue(company.getId(), cPowerSharpPointMap, datePointValueMap, yesterdayPointValueMap);
                        electricityDay.setSharp(powerSharp);
                        double powerPeak = getPointValue(company.getId(), cPowerPeakPointMap, datePointValueMap, yesterdayPointValueMap);
                        electricityDay.setPeak(powerPeak);
                        double powerFlat = getPointValue(company.getId(), cPowerFlatPointMap, datePointValueMap, yesterdayPointValueMap);
                        electricityDay.setFlat(powerFlat);
                        double powerValley = getPointValue(company.getId(), cPowerValleyPointMap, datePointValueMap, yesterdayPointValueMap);
                        electricityDay.setValley(powerValley);
                        electricityDayList.add(electricityDay);
                    }
                }
            }

            //组建单位电量
            ElectricityDay fElectricityDay = new ElectricityDay();
            fElectricityDay.setDtime(yesterday.get(0));
            fElectricityDay.setDeviceId(firm.getId());
            fElectricityDay.setVal(fPowerAll);
            fElectricityDay.setSharp(fPowerSharp);
            fElectricityDay.setPeak(fPowerPeak);
            fElectricityDay.setFlat(fPowerFlat);
            fElectricityDay.setValley(fPowerValley);
            electricityDayList.add(fElectricityDay);

            //插入电量统计
            energyClient.postDay(new DomainList<>(electricityDayList));
        }
    }

    public void calculateMonth(Long firmCode) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date monthDate = calendar.getTime();

        calendar.add(Calendar.MONTH, -1);
        Date startDate = calendar.getTime();

        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        Date endDate = calendar.getTime();

        List<ElectricityDay> dayList = energyClient.searchDay(Arrays.asList(startDate, endDate)).getBody().getResults();
        if (dayList != null) {
            Map<Long, ElectricityMonth> monthMap = new HashMap<>();
            for (ElectricityDay item : dayList) {
                Long deviceId = item.getDeviceId();
                ElectricityMonth month = monthMap.computeIfAbsent(deviceId, k -> new ElectricityMonth());
                month.setDeviceId(deviceId);
                month.setDtime(monthDate);
                month.setVal(month.getVal() == null ? item.getVal() : month.getVal() + item.getVal());
                month.setSharp(month.getSharp() == null ? item.getSharp() : month.getSharp() + item.getSharp());
                month.setPeak(month.getPeak() == null ? item.getPeak() : month.getPeak() + item.getPeak());
                month.setFlat(month.getFlat() == null ? item.getFlat() : month.getFlat() + item.getFlat());
                month.setValley(month.getValley() == null ? item.getValley() : month.getValley() + item.getValley());
            }
            List<ElectricityMonth> results = new ArrayList<>(monthMap.values());
            energyClient.postMonth(new DomainList<>(results));
        }
    }

    private double getPointValue(Long deviceId,
                                 Map<Long, List<Long>> powerPointMap,
                                 Map<Long, Double> datePointValueMap,
                                 Map<Long, Double> yesterdayPointValueMap) {
        List<Long> powerAllPoints = powerPointMap.get(deviceId);
        double value = 0L;
        if (powerAllPoints != null && powerAllPoints.size() > 0) {
            for (Long point : powerAllPoints) {
                Double dateValue = datePointValueMap.get(point);
                Double yesterdayValue = yesterdayPointValueMap.get(point);
                if (dateValue != null && yesterdayValue != null) {
                    value += (dateValue - yesterdayValue);
                }
            }
        }
        return value;
    }

    private void joinPointNumber(List<Long> pointNumbers, Map<Long, List<Long>> map) {
        for (List<Long> points : map.values()) {
            pointNumbers.addAll(points);
        }
    }
}
